package com.example.eduservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.commonsutils.R;
import com.example.common.exception.GuliException;
import com.example.eduservice.entity.EduComment;
import com.example.eduservice.entity.frontvo.CommentFrontVO;
import com.example.eduservice.mapper.EduCommentMapper;
import com.example.eduservice.service.EduCommentService;
import com.example.eduservice.service.UCenterFeignService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author:tjf
 * @Description:
 */
@Service
public class EduCommentServiceImpl extends ServiceImpl<EduCommentMapper, EduComment> implements EduCommentService {
    @Resource
    private UCenterFeignService uCenterFeignService;
    @Resource
    private EduCommentMapper commentMapper;
    /**
     * 保存课程的评论
     * @param commentVO
     * @param token
     */
    @Override
    public void saveCourseComment(CommentFrontVO commentVO, String token) {
        EduComment eduComment = new EduComment();
        BeanUtils.copyProperties(commentVO, eduComment);

        // 获取评论的会员信息
        Map<String, Object> data = queryMemberInfo(token);
        if (data != null){
            eduComment.setMemberId((String)data.get("id"));
            eduComment.setNickname((String)data.get("nickname"));
            eduComment.setAvatar((String)data.get("avatar"));
            commentMapper.insert(eduComment);
        }else{
            throw new GuliException(20001, "评论失败！请先登录");
        }
    }

    /**
     * 获取课程的评论
     *
     * @param courseId
     * @param teacherId
     * @param page
     * @return
     */
    @Override
    public Map<String, Object> queryCourseComment(String courseId, String teacherId, Page<EduComment> page) {
        List<CommentFrontVO> commentFrontVOList = new ArrayList<>();
        // 到数据库查询评论(带分页)
        LambdaQueryWrapper<EduComment> commentWrapper = new LambdaQueryWrapper<>();
        commentWrapper.eq(EduComment::getCourseId, courseId)
                        .eq(EduComment::getTeacherId, teacherId)
                        .isNull(EduComment::getReplyCommentId)
                        .isNull(EduComment::getReplyMemberId)
                        .orderByDesc(EduComment::getGmtCreate);

        Page<EduComment> commentPage = commentMapper.selectPage(page, commentWrapper);
        List<EduComment> comments = commentPage.getRecords();

        Map<String, Object> result = new HashMap<>();
        result.put("total", commentPage.getTotal());
        result.put("current", commentPage.getCurrent());
        // 遍历每条评论并查询对应的回复(带分页)
        if (comments != null && comments.size() > 0){
            for (EduComment comment : comments) {
                CommentFrontVO commentFrontVO = new CommentFrontVO();
                BeanUtils.copyProperties(comment, commentFrontVO);
                // 查询该评论的回复并封装数据(feign请求被回复人的信息(保证nickname实时))
                Map<String, Object> replies = queryCommentReplies(comment.getId(),
                                                    new Page<EduComment>(1, 3));
                commentFrontVO.setReplies(replies);
                commentFrontVOList.add(commentFrontVO);
            }
        }
        result.put("comments", commentFrontVOList);
        return result;
    }

    /**
     * 查询评论的回复并分页
     * @param replyCommentId 被回复的评论id
     * @param page 分页对象
     * @return
     */
    @Override
    public Map<String, Object> queryCommentReplies(String replyCommentId,
                                                   Page<EduComment> page){
        List<CommentFrontVO> commentReplies = new ArrayList<>();
        // 查询评论的回复并按回复时间降序排序
        LambdaQueryWrapper<EduComment> commentWrapper = new LambdaQueryWrapper<>();
        commentWrapper.eq(EduComment::getReplyCommentId, replyCommentId)
                        .orderByDesc(EduComment::getGmtCreate);;

        // 分页查询回复
        Page<EduComment> commentPage = commentMapper.selectPage(page, commentWrapper);
        List<EduComment> replies = commentPage.getRecords();
        Map<String, Object> map = new HashMap<>();
        // 只要需要的两个基本参数
        map.put("current", commentPage.getCurrent());
        map.put("total", commentPage.getTotal());

        // 获取每条回复中被回复会员的nickname并把数据封装到VO中
        if (replies != null && replies.size() > 0){
            for (EduComment reply : replies) {
                // 封装返回前端的数据对象
                CommentFrontVO replyVO = new CommentFrontVO();
                BeanUtils.copyProperties(reply, replyVO);
                // 查询被回复的评论的会员信息
                Map<String, Object> result = getMemberInfo(reply.getReplyMemberId());
                if (result != null){
                    replyVO.setReplyMemberNickName((String) result.get("nickname"));
                    commentReplies.add(replyVO);
                }
            }
            map.put("replies", commentReplies);
        }
        // 无论有没有回复，需返回总数以及当前页
        return map;
    }

    /**
     * 获取会员信息
     * @param replyMemberId
     * @return
     */
    private Map<String, Object> getMemberInfo(String replyMemberId) {
        if (StringUtils.isNotBlank(replyMemberId)){
            //todo_tjf (tjf,2024/3/4,Com_T) 为code==20001作判断
            R response = uCenterFeignService.getMemberInfoById(replyMemberId);
            Map<String, Object> map = (Map<String, Object>) response.getData().get("memberInfo");
            return map;
        }else{
            return null;
        }
    }

    /**
     * 根据前端请求获取会员的信息
     * @param token
     * @return
     */
    private Map<String, Object> queryMemberInfo(String token) {
        // 获取会员的信息
        R response = uCenterFeignService.getUserInfoByToken(token);
        if (response.getCode() == 20000){
            Map<String, Object> data = (Map<String, Object>)response.getData().get("loginMember");
            return data;
        }else{
            System.out.println(response.getMessage());
            throw new GuliException(20001, response.getMessage());
        }
    }
}
